//
//  DownManager.m
//  MiBaoTu
//
//  Created by admin on 16/9/23.
//  Copyright © 2016年 com.caesartech15. All rights reserved.
//

#import "DownManager.h"

#define DOWNING_MUSIC_COUNT (3)

@interface DownManager ()<NSCopying,NSURLSessionDelegate> {
    NSString        *_userId;
    NSString        *_content;
    NSString        *_picUrl;
    NSString        *_date;
    NSString        *_userPic;
    NSString        *_userNick;
    NSString        *_fileSize;
    
    BOOL            isQZX;
    BOOL            isAllPause; //是否全部暂停
}

/** 保存所有任务(注：用下载地址/后作为key) */
@property (nonatomic, strong) NSMutableDictionary *tasks;
/** 保存所有下载相关信息字典 */
@property (nonatomic, strong) NSMutableDictionary *sessionModels;
/** 所有本地存储的所有下载信息数据数组 */
@property (nonatomic, strong) NSMutableArray *sessionModelsArray;
/** 下载中的模型数组*/
@property (nonatomic, strong) NSMutableArray *downloadingArray;
/** 下载完成的模型数组*/
@property (nonatomic, strong) NSMutableArray *downloadedArray;


@end
@implementation DownManager

+ (instancetype)staredInstance
{
    static DownManager *downManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        downManager = [[self alloc]init];
    });
    return downManager;
}

- (id)init
{
    self = [super init];
    if (self) {
        
    }
    return self;
}

#pragma mark - 开始下载
- (void)downloadWithUrl:(NSString *)urlString
          withMusicName:(NSString *)musicFullName
             withUserID:(NSString *)userID
            withMusicID:(NSString *)musicID
            withContent:(NSString *)content
          withMusicType:(NSString *)type
             withPicUrl:(NSString *)picUrl
               withDate:(NSString *)date
            withUserPic:(NSString *)userPic
           withUserNick:(NSString *)nick
               withSize:(NSString *)size
           withProgress:(DownLoadProgressBlock)progressBlock
              withStats:(DownLoadStatsBlock)statsBlock
{
    _userId = userID;
    _content = content;
    _picUrl = picUrl;
    _date = date;
    _userPic = userPic;
    _userNick = nick;
    _fileSize = size;
    isQZX = YES;
    
    [self downloadWithUrl:urlString
            withMusicName:musicFullName
              withMusicID:musicID
            withMusicType:type
             withProgress:progressBlock withStats:statsBlock];
}

- (void)downloadWithUrl:(NSString *)urlString
          withMusicName:(NSString *)musicFullName
            withMusicID:(NSString *)musicID
          withMusicType:(NSString *)type
           withProgress:(DownLoadProgressBlock)progressBlock
              withStats:(DownLoadStatsBlock)statsBlock
{
    if (!urlString) {
        return;
    }
    
    //创建缓存地址
    [self onCreateCacheDirectory];
    //创建输出流
    NSString *musicName = [musicFullName componentsSeparatedByString:@"."][0];
    NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:musicFullName];
    if (isQZX) {
        filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"qzx_%@",musicFullName]];
    }
    //*****************如果已下载，未删除干净****************
    NSFileManager *fileManager = [NSFileManager defaultManager];
    //已下载歌曲记录
    BOOL isDownedMusic = NO;
    NSArray *downedMusicArr = [UserManager standerDefult].downedMusicArr;
    for (int i=0; i<downedMusicArr.count; i++) {
        NSDictionary *dic = [downedMusicArr objectAtIndex:i];
        NSString *fileID = [dic objectForKey:@"fileID"];
        NSString *types = [dic objectForKey:@"type"];
        if ([fileID intValue] == [musicID intValue] && [type intValue] == [types intValue]) {
            //音频数据库有记录
            isDownedMusic = YES;
        }
    }
    //已下载的亲子秀
    NSArray *downedQZXMusicArr = [[FMManageObject standerDefault]onSelectLocalParentChildShowCount];
    for (int i=0; i<downedQZXMusicArr.count; i++) {
        NSDictionary *dic = [downedQZXMusicArr objectAtIndex:i];

        NSString *fileID = [dic objectForKey:@"musicId"];
         NSString *types = [dic objectForKey:@"type"];
        if ([fileID intValue] == [musicID intValue] && [type intValue] == [types intValue]) {
            //亲子秀数据库有记录
            isDownedMusic = YES;
        }
    }
    if (isDownedMusic == NO) {
        //没有记录在数据库：已从数据库删除或未下载过
        if ([fileManager fileExistsAtPath:filePath]) {
            [fileManager removeItemAtPath:filePath error:nil];
        }
    }
    //*****************
    
    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:filePath append:YES];
//    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:MusicFilelpath(urlString) append:YES];
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    //请求 range请求头必写，断点续传效果
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    NSString *range = [NSString stringWithFormat:@"bytes=%llu-",[[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize]];
    [request setValue:range forHTTPHeaderField:@"Range"];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
    NSUInteger taskIdentifier = arc4random() % (arc4random()%10000 + arc4random()%10000);
    [task setValue:@(taskIdentifier) forKeyPath:@"taskIdentifier"];
    
    //保持下载任务
    [self.tasks setValue:task forKey:musicFullName];
    
    DownMusicModel *model = [[DownMusicModel alloc]init];
    if (![fileManager fileExistsAtPath:filePath]) {
        model.url = urlString;
        model.musicID = [NSString stringWithFormat:@"%@",musicID];
        model.musicType = type;
        model.progressBlock = progressBlock;
        model.stateBlock = statsBlock;
        model.stream = outStream;
        model.startTime = [NSDate date];
        model.fileName = musicName;
        model.userID = (_userId.length > 0 ? _userId : @"");
        model.content = (_content.length > 0 ? _content : @"");
        model.picUrl =(_picUrl.length > 0 ? _picUrl : @"");
        model.date = (_date.length > 0 ? _date : @"");
        model.userPic = (_userPic.length > 0 ? _userPic : @"");
        model.userNick = (_userNick.length > 0 ? _userNick : @"");
        model.size = (_fileSize.length > 0 ? _fileSize : @"");
        model.isDowning = @"1";
        
        [self.sessionModels setValue:model forKey:@(task.taskIdentifier).stringValue];

        BOOL isExit = NO;
        for (DownMusicModel *nM in self.sessionModelsArray) {
            if ([nM.musicID intValue] == [model.musicID intValue]) {
                isExit = YES;
            }
        }
        if (isExit == NO) {
            [self.sessionModelsArray addObject:model];
        }
        
        [self.downloadingArray addObject:model];
        
        //归档保持
        [self save:self.sessionModelsArray];
    } else {
        if (self.sessionModelsArray.count > 0) {
            for (DownMusicModel *models in self.sessionModelsArray) {
                if ([models.url isEqualToString:urlString]) {
                    models.url = urlString;
                    models.musicID = musicID;
                    models.musicType = type;
                    models.progressBlock = progressBlock;
                    models.stateBlock = statsBlock;
                    models.stream = outStream;
                    models.startTime = [NSDate date];
                    models.fileName = musicName;
                    models.userID = (_userId.length > 0 ? _userId : @"");
                    models.content = (_content.length > 0 ? _content : @"");
                    models.picUrl =(_picUrl.length > 0 ? _picUrl : @"");
                    models.date = (_date.length > 0 ? _date : @"");
                    models.userPic = (_userPic.length > 0 ? _userPic : @"");
                    models.userNick = (_userNick.length > 0 ? _userNick : @"");
                    models.size = (_fileSize.length > 0 ? _fileSize : @"");
                    models.isDowning = @"1";
                    model = models;
                    [self.sessionModels setValue:model forKey:@(task.taskIdentifier).stringValue];
                }
            }
        } else {
            if ([fileManager fileExistsAtPath:filePath]) {
                [fileManager removeItemAtPath:filePath error:nil];
            }
        }
    }
    
    isAllPause = NO;
    
    if ([UserManager standerDefult].downingMusicCountArr.count < DOWNING_MUSIC_COUNT) {
        BOOL isExit = NO;
        for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
            if ([nM.musicID intValue] == [model.musicID intValue] && [nM.musicType intValue] == [model.musicType intValue]) {
                isExit = YES;
            }
        }
        if (isExit == NO) {
            [[UserManager standerDefult].downingMusicCountArr addObject:model];
            //开始下载
            [self start:musicFullName];
        }
    } else {
        [[UserManager standerDefult].waitDownMusicCountArr addObject:model];
    }
}

#pragma mark - Actions
//创建下载缓存目录地址
- (void)onCreateCacheDirectory
{
//    NSString *ss =[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]stringByAppendingPathComponent:@"MusicCache"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:MusicCachesDirectory]) {
        [fileManager createDirectoryAtPath:MusicCachesDirectory withIntermediateDirectories:YES attributes:nil error:NULL];
    }
}

- (NSMutableDictionary *)tasks
{
    if (!_tasks) {
        _tasks = [NSMutableDictionary dictionary];
    }
    return _tasks;
}

- (NSMutableDictionary *)sessionModels
{
    if (!_sessionModels) {
        _sessionModels = @{}.mutableCopy;
    }
    return _sessionModels;
}

- (NSMutableArray *)sessionModelsArray
{
    if (!_sessionModelsArray) {
        _sessionModelsArray = @[].mutableCopy;
        NSArray *arr = [self getSessionModels];
        for (DownMusicModel *model in arr) {
            if (_sessionModelsArray.count == 0) {
                [_sessionModelsArray addObject:model];
            } else {
                BOOL isExit = NO;
                for (DownMusicModel *nM in _sessionModelsArray) {
                    if ([nM.musicID intValue] == [model.musicID intValue]) {
                        isExit = YES;
                    }
                }
                if (isExit == NO) {
                    [_sessionModelsArray addObject:model];
                }
            }
        }

    }
    return _sessionModelsArray;
}

- (NSMutableArray *)downloadingArray
{
    if (!_downloadingArray) {
        _downloadingArray = @[].mutableCopy;
        for (DownMusicModel *obj in self.sessionModelsArray) {
            NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",obj.fileName]];
            if (![self isCompletion:obj.url withFilePath:filePath]) {
                //避免重复添加 大爷烦死了
                BOOL isExit = NO;
                for (DownMusicModel *mm in _downloadingArray) {
                    if ([mm.musicID intValue] == [obj.musicID intValue]) {
                        isExit = YES;
                    }
                }
                if (isExit == NO) {
                    [_downloadingArray addObject:obj];
                }
            }
        }
    }
    return _downloadingArray;
}

- (NSMutableArray *)downloadedArray
{
    if (!_downloadedArray) {
        _downloadedArray = @[].mutableCopy;
        for (DownMusicModel *obj in self.sessionModelsArray) {
            NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",obj.fileName]];
            if ([self isCompletion:obj.url withFilePath:filePath]) {
                [_downloadedArray addObject:obj];
            }
        }
    }
    return _downloadedArray;
}

//开始下载
- (void)start:(NSString *)url
{
    NSURLSessionDataTask *task = [self getTask:url];
    [task resume];
}

/**
 *  暂停下载
 */
- (void)pause:(NSString *)url
{
    NSURLSessionDataTask *task = [self getTask:url];
    [task suspend];
    
    [self getSessionModel:task.taskIdentifier].stateBlock(DownMusicState_Suspended);
}

/*
 * 全部暂停,返回数组包含未正在下载状态的音频
 */
- (NSMutableArray *)pauseAllMusic:(BOOL)isSuspend
{
    isAllPause = isSuspend;
    
    if ([UserManager standerDefult].downingMusicCountArr.count == 0) {
        //没有正在下载的
        NSArray *sessionModels = [NSKeyedUnarchiver unarchiveObjectWithFile:DownloadDetailPath];
        if (sessionModels.count > 0) {
            //上次正在下载被over的
            for (DownMusicModel *model in sessionModels) {
                   if ([model.musicType intValue] >= 5 && [model.musicType intValue] <= 6) {
                       dispatch_async(dispatch_get_global_queue(0, 0), ^{
                       [self downloadWithUrl:model.url
                               withMusicName:[NSString stringWithFormat:@"%@.mp3",model.fileName]
                                  withUserID:model.userID
                                 withMusicID:model.musicID
                                 withContent:model.content
                               withMusicType:model.musicType
                                  withPicUrl:model.picUrl
                                    withDate:model.date
                                 withUserPic:model.userPic
                                withUserNick:model.userNick
                                    withSize:model.size
                                withProgress:^(CGFloat progress, NSString *speed, NSString *remainingTime, NSString *writtenSize, NSString *totalSize) {
                                    
                                } withStats:^(DownMusicState stats) {
                                    
                                }];
                       });
                       
                   } else {
                       NSString *audioName = [NSString stringWithFormat:@"%@.%@",model.fileName,[[model.url componentsSeparatedByString:@"."] lastObject]];
                       NSDictionary *dic = @{@"ID":model.musicID,
                                             @"AudioPath":[model.url componentsSeparatedByString:MUSIC_PLAY_Url].lastObject,
                                             @"AudioName":audioName,
                                             @"ValueID":model.musicType};
                       [[UserManager standerDefult]downLoadMusic:dic withRequestArr:@[]];
                   }
            }
            return @[].mutableCopy;
        }
    }
    
    NSMutableArray *nArr = [[NSMutableArray alloc]initWithCapacity:[UserManager standerDefult].downingMusicCountArr.count];
    NSMutableArray *musicArr = [[NSMutableArray alloc]init];

    
    for (DownMusicModel *musicModel in [UserManager standerDefult].downingMusicCountArr) {
        DownMusicModel *nModel = [[DownMusicModel alloc]init];
        if (isSuspend == NO) {
            nModel.progressBlock = musicModel.progressBlock;
            nModel.stateBlock = musicModel.stateBlock;
            nModel.stream = musicModel.stream;
        }
        nModel.url = musicModel.url;
        nModel.startTime = musicModel.startTime;
        nModel.fileName = musicModel.fileName;
        nModel.totalSize = musicModel.totalSize;
        nModel.musicID = musicModel.musicID;
        nModel.musicType = musicModel.musicType;
        nModel.userID = musicModel.userID;
        nModel.content = musicModel.content;
        nModel.picUrl = musicModel.picUrl;
        nModel.date = musicModel.date;
        nModel.userPic = musicModel.userPic;
        nModel.userNick = musicModel.userNick;
        nModel.size = musicModel.size;
        nModel.totalLength = musicModel.totalLength;
        nModel.isDowning = (isSuspend?@"0":@"1");
        
        [nArr addObject:nModel];
        
        NSString *url = [NSString stringWithFormat:@"%@.%@",musicModel.fileName,[[musicModel.url componentsSeparatedByString:@"."] lastObject]];
        if ([nModel.musicType intValue] >= 5) {
            url = [NSString stringWithFormat:@"qzx_%@.%@",musicModel.fileName,[[musicModel.url componentsSeparatedByString:@"."] lastObject]];
        }
        if (isSuspend) {
            NSURLSessionDataTask *task = [self getTask:url];
            if (task) {
                if (task.state != NSURLSessionTaskStateSuspended) {
                    [task suspend];
                }
                [self getSessionModel:task.taskIdentifier].stateBlock(DownMusicState_Suspended);
            }
            
        } else {
            
            NSURLSessionDataTask *task = [self getTask:url];
            if (task) {
                if (task.state == NSURLSessionTaskStateRunning) {
                    
                }
                else if (task.state == NSURLSessionTaskStateSuspended) {
                    [task resume];
                }
                else if (task.state == NSURLSessionTaskStateCompleted) {
                    [musicArr addObject:nModel];
                }
            } else {
                [musicArr addObject:nModel];
            }
        }
        
    }
    
    //在下载队列的歌曲或亲子秀已经失效
    //1.从下载队列移动
    if (musicArr.count > 0) {
        for (DownMusicModel *model in musicArr) {
            isAllPause = NO;
            if ([UserManager standerDefult].downingMusicCountArr.count <= DOWNING_MUSIC_COUNT) {
                BOOL isExit = NO;
                DownMusicModel *nMusicModel;
                for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                    if ([nM.musicID intValue] == [model.musicID intValue] && [nM.musicType intValue] == [model.musicType intValue]) {
                        isExit = YES;
                        nMusicModel = nM;
                    }
                }
                if (isExit == YES) {
                    //已下载完成 删除该nextModel，加载别的nextModel
                    [[UserManager standerDefult].downingMusicCountArr removeObject:nMusicModel];
                    
                }
                //2.重新添加
                if ([model.musicType intValue] >= 5 && [model.musicType intValue] <= 6) {
                    dispatch_async(dispatch_get_global_queue(0, 0), ^{
                        [self downloadWithUrl:model.url
                                withMusicName:[NSString stringWithFormat:@"%@.mp3",model.fileName]
                                   withUserID:model.userID
                                  withMusicID:model.musicID
                                  withContent:model.content
                                withMusicType:model.musicType
                                   withPicUrl:model.picUrl
                                     withDate:model.date
                                  withUserPic:model.userPic
                                 withUserNick:model.userNick
                                     withSize:model.size
                                 withProgress:^(CGFloat progress, NSString *speed, NSString *remainingTime, NSString *writtenSize, NSString *totalSize) {
                                     
                                 } withStats:^(DownMusicState stats) {
                                     
                                 }];
                    });
                    
                } else {
                    NSString *audioName = [NSString stringWithFormat:@"%@.%@",model.fileName,[[model.url componentsSeparatedByString:@"."] lastObject]];
                    if (![audioName isEqualToString:@"(null).(null)"]) {
                        NSDictionary *dic = @{@"ID":model.musicID,
                                              @"AudioPath":[model.url componentsSeparatedByString:MUSIC_PLAY_Url].lastObject,
                                              @"AudioName":audioName,
                                              @"ValueID":model.musicType};
                        [[UserManager standerDefult]downLoadMusic:dic withRequestArr:@[]];
                    }
                }
                
            }

        }
    }
    

    
    return @[];
}

/**
 *  根据url获得对应的下载任务 NSURLSessionDataTask
 */
- (NSURLSessionDataTask *)getTask:(NSString *)url
{
    return (NSURLSessionDataTask *)[self.tasks valueForKey:url];
}

/**
 * 读取model
 */
- (NSArray *)getSessionModels
{
    // 文件信息
    NSArray *sessionModels = [NSKeyedUnarchiver unarchiveObjectWithFile:DownloadDetailPath];
    return sessionModels;
}

/**
 * 归档
 */
- (void)save:(NSArray *)sessionModels
{
    [NSKeyedArchiver archiveRootObject:sessionModels toFile:DownloadDetailPath];
}

/**
 *  获取该资源总大小
 */
- (NSInteger)fileTotalLength:(NSString *)url
{
    for (DownMusicModel *model in self.sessionModelsArray) {
        if ([model.url isEqualToString:url]) {
            return model.totalLength;
        }
    }
    return 0;
}

/**
 *  判断该文件是否下载完成
 */
- (BOOL)isCompletion:(NSString *)url withFilePath:(NSString *)filePath
{
    NSInteger downedCount = DownloadLength(filePath);
    if ([self fileTotalLength:url] && downedCount == [self fileTotalLength:url]) {
        return YES;
    }
    return NO;
}

/**
 *  根据url获取对应的下载信息模型
 */
- (DownMusicModel *)getSessionModel:(NSUInteger)taskIdentifier
{
    return (DownMusicModel *)[self.sessionModels valueForKey:@(taskIdentifier).stringValue];
}

/**
 *  查询该资源的下载进度值
 */
- (CGFloat)progress:(NSString *)url withFilePath:(NSString *)filePath
{
    return [self fileTotalLength:url] == 0 ? 0.0 : 1.0 * DownloadLength(filePath) /  [self fileTotalLength:url];
}

/**
 *  删除该资源
 */
//- (void)deleteFile:(NSString *)path withMusicID:(NSString *)idStr
- (void)deleteFile:(DownMusicModel *)musicModel
{
    NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",musicModel.fileName]];
    NSURLSessionDataTask *task = [self getTask:[NSString stringWithFormat:@"%@.mp3",musicModel.fileName]];
    if (task) {
        // 取消下载
        [task cancel];
    }
    //正在进行下载
    DownMusicModel *nMusicModel;
    for (DownMusicModel *model in [UserManager standerDefult].downingMusicCountArr) {
        if ([model.musicID intValue] == [musicModel.musicID intValue] && [model.musicType intValue] == [musicModel.musicType intValue]) {
            nMusicModel = model;
        }
    }
    if ([[UserManager standerDefult].downingMusicCountArr containsObject:nMusicModel]) {
        [[UserManager standerDefult].downingMusicCountArr removeObject:nMusicModel];
    }
    
    //还没进行下载，在等待中
    for (DownMusicModel *model in [UserManager standerDefult].waitDownMusicCountArr) {
        if ([model.musicID intValue] == [musicModel.musicID intValue] && [model.musicType intValue] == [musicModel.musicType intValue]) {
            nMusicModel = model;
        }
    }
    if ([[UserManager standerDefult].waitDownMusicCountArr containsObject:nMusicModel]) {
        [[UserManager standerDefult].waitDownMusicCountArr removeObject:nMusicModel];
    }
    
    if ([UserManager standerDefult].downingMusicCountArr.count < DOWNING_MUSIC_COUNT) {
        BOOL isExit = NO;
        DownMusicModel *nMusicModel;
        for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
            if ([nM.musicID intValue] == [musicModel.musicID intValue] && [nM.musicType intValue] == [musicModel.musicType intValue]) {
                isExit = YES;
                nMusicModel = nM;
            }
        }
        if (isExit == NO) {
            //已下载完成 删除该nextModel，加载别的nextModel
            
            if ([UserManager standerDefult].waitDownMusicCountArr.count > 0) {
                DownMusicModel *nextModel = [[UserManager standerDefult].waitDownMusicCountArr firstObject];
                BOOL isExit = NO;
                for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                    if ([nM.musicID intValue] == [nextModel.musicID intValue] && [nM.musicType intValue] == [nextModel.musicType intValue]) {
                        isExit = YES;
                    }
                }
                if (isExit == NO) {
                    [[UserManager standerDefult].downingMusicCountArr addObject:nextModel];
                    //开始下载
                    if (isAllPause == NO) {
                        [self start:[NSString stringWithFormat:@"%@.mp3",nextModel.fileName]];
                    }
                    [[UserManager standerDefult].waitDownMusicCountArr removeObject:nextModel];
                }
            }
            
        }
        
    }

    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:filePath]) {
       
        // 删除沙盒中的资源
        [fileManager removeItemAtPath:filePath error:nil];
    }
    
    // 从沙盒中移除该条模型的信息
     NSString *url;
    for (DownMusicModel *model in self.sessionModelsArray.mutableCopy) {
        if ([model.musicID intValue] == [musicModel.musicID intValue] && [model.musicType intValue] == [musicModel.musicType intValue]) {
            // 关闭流
            [model.stream close];
            [self.sessionModelsArray removeObject:model];
            url = model.url;
            //清除临时
            if ([[UserManager standerDefult].tempMusicArr containsObject:[NSString stringWithFormat:@"%@",model.musicID]]) {
                [[UserManager standerDefult].tempMusicArr removeObject:[NSString stringWithFormat:@"%@",model.musicID]];
            }
        }
    }
    
    if (url.length > 0) {
        // 删除任务
        [self.tasks removeObjectForKey:[NSString stringWithFormat:@"%@.mp3",musicModel.fileName]];
        [self.sessionModels removeObjectForKey:@([self getTask:url].taskIdentifier).stringValue];
        // 保存归档信息
        [self save:self.sessionModelsArray];
    }
}

/**
 *  清空所有下载资源
 */
- (void)deleteAllFile
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:MusicCachesDirectory]) {
        
        // 删除沙盒中所有资源
        [fileManager removeItemAtPath:MusicCachesDirectory error:nil];
        // 删除任务
        [[self.tasks allValues] makeObjectsPerformSelector:@selector(cancel)];
        [self.tasks removeAllObjects];
        
        for (DownMusicModel *sessionModel in [self.sessionModels allValues]) {
            [sessionModel.stream close];
            
            //清除临时
            if ([[UserManager standerDefult].tempMusicArr containsObject:[NSString stringWithFormat:@"%@",sessionModel.musicID]]) {
                [[UserManager standerDefult].tempMusicArr removeObject:[NSString stringWithFormat:@"%@",sessionModel.musicID]];
            }
        }
        [self.sessionModels removeAllObjects];
        
        // 删除资源总长度
        if ([fileManager fileExistsAtPath:DownloadDetailPath]) {
            [fileManager removeItemAtPath:DownloadDetailPath error:nil];
            [self.sessionModelsArray removeAllObjects];
            self.sessionModelsArray = nil;
            [self.downloadedArray removeAllObjects];
            [self.downloadingArray removeAllObjects];
        }
    }
}

/*
 * 正在下载任务
 */
- (NSArray *)currentDownloads {
    NSMutableArray *currentDownloads = [NSMutableArray new];
    [self.sessionModels enumerateKeysAndObjectsUsingBlock:^(id key, DownMusicModel *download, BOOL *stop) {
        [currentDownloads addObject:download];
    }];
    return currentDownloads;
}

/*
 * 判断是否正在下载
 */
- (BOOL)isFileDownloadingForUrl:(NSString *)url withProgressBlock:(DownLoadProgressBlock)block
{
    BOOL retValue = NO;
    NSURLSessionDataTask *task = [self getTask:url];
    DownMusicModel *session = [self getSessionModel:task.taskIdentifier];
    if (session) {
        if (block) {
            session.progressBlock = block;
        }
        retValue = YES;
    }
    return retValue;
}

#pragma mark NSURLSessionDataDelegate

/**
 * 接收到响应
 */
- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSHTTPURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    DownMusicModel *model = [self getSessionModel:dataTask.taskIdentifier];
    
    //打开流，开始接受数据准备
    [model.stream open];
    
    //本地已下载的和服务器未下载下来的总数据
    NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]];
    if (isQZX) {
        filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"qzx_%@.mp3",model.fileName]];
    }
    NSInteger totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + DownloadLength(filePath);
    model.totalLength = totalLength;
    
    //总大小 xxG、xxM
    NSString *fileSize = [NSString stringWithFormat:@"%.2f%@",[model calculateFileSizeInUnit:(unsigned long long)totalLength],[model calculateUnit:(unsigned long long)totalLength]];
    model.totalSize = fileSize;
    
    //更新
    [self save:self.sessionModelsArray];
    
    //确认，添加
    if (![self.downloadingArray containsObject:model] && model) {
        [self.downloadingArray addObject:model];
    }
    
    // 接收这个请求，允许接收服务器的数据
    completionHandler(NSURLSessionResponseAllow);
}

/**
 * 接收到服务器返回的数据
 */
- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data
{
    DownMusicModel *model = [self getSessionModel:dataTask.taskIdentifier];
    
    //写入数据
    [model.stream write:data.bytes maxLength:data.length];
    
    //下载进度
    NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]];
    if (isQZX) {
        filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"qzx_%@.mp3",model.fileName]];
    }
    NSUInteger receivedSize = DownloadLength(filePath);
    NSUInteger totalSize = model.totalLength;
    CGFloat progress = 1.0 * receivedSize / totalSize;
    
    //每秒下载速度
    NSTimeInterval downloadTime = -1 * [model.startTime timeIntervalSinceNow];
    NSUInteger speed = receivedSize / downloadTime;
    if (speed == 0) {
        return;
    }
    float speedSec = [model calculateFileSizeInUnit:(unsigned long long) speed];
    NSString *speedString = [model calculateUnit:(unsigned long long) speed];
    NSString *speedStr = [NSString stringWithFormat:@"%.2f%@/s",speedSec,speedString];
    
    //剩余下载时间
    NSMutableString *remainingTimeStr = [[NSMutableString alloc] init];
    unsigned long long remainingContentLength = totalSize - receivedSize;
    int remainingTime = (int)(remainingContentLength / speed);
    int hours = remainingTime / 3600;
    int minutes = (remainingTime - hours * 3600) / 60;
    int seconds = remainingTime - hours * 3600 - minutes * 60;
    
    if(hours>0) {
        [remainingTimeStr appendFormat:@"%d 小时 ",hours];
    }
    if(minutes>0) {
        [remainingTimeStr appendFormat:@"%d 分 ",minutes];
    }
    if(seconds>0) {
        [remainingTimeStr appendFormat:@"%d 秒",seconds];
    }
    
    NSString *writtenSize = [NSString stringWithFormat:@"%.2f %@",
                             [model calculateFileSizeInUnit:(unsigned long long)receivedSize],
                             [model calculateUnit:(unsigned long long)receivedSize]];
    
    NSLog(@"************************\n正在下载歌曲名称:%@ \n下载进度:%.2f \n美秒下载速度:%@ \n下载剩余时间:%@************************\n",model.fileName,progress,speedStr,remainingTimeStr);
    
    if (model.stateBlock) {
        model.stateBlock(DownMusicState_Start);
    }
    if (model.progressBlock) {
        model.progressBlock(progress,speedStr,remainingTimeStr,writtenSize,model.totalSize);
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if ([self.delegate respondsToSelector:@selector(downloadResponse:)]) {
            [self.delegate downloadResponse:model];
        }
    });
}

/**
 * 请求完毕（成功|失败）
 */
- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
    DownMusicModel *model = [self getSessionModel:task.taskIdentifier];
    if (!model) {
        return;
    }
    
    //流关闭
    [model.stream close];
    model.stream = nil;
    
    //是否下载完整
    NSString *filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]];
    if (isQZX) {
        filePath = [MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"qzx_%@.mp3",model.fileName]];
    }
    
    BOOL isCompeted = NO;
    if ([self isCompletion:model.url withFilePath:filePath]) {
        isCompeted = YES;
        if (model.stateBlock) {
            model.stateBlock(DownMusicState_Completed);
        }
        
        //写入数据库
        FMManageObject *managerFM = [FMManageObject standerDefault];
        
        if (model.userID.length > 0) {
            //亲子秀
            NSDictionary *dic = [[managerFM onSelectLocalParentChildShowCount]lastObject];
            [managerFM insertTableByLocalParentChildShowWithId:[NSString stringWithFormat:@"%d",[[dic objectForKey:@"id"] intValue]+1] withTitle:model.fileName withUserId:model.userID withMusicId:model.musicID withContent:model.content withType:model.musicType withPicture:model.picUrl withDate:model.date withMp3:model.url withUserPic:model.userPic withUserNick:model.userNick withSize:model.size];
            
        } else {
           
            NSArray *musicDownedArr = [managerFM onSelectCustomMusicFileCount];
            [managerFM insertTableWithId:[NSString stringWithFormat:@"%d",((int)musicDownedArr.count+1)]
                            withFileName:model.fileName
                              withFileID:model.musicID
                                 withUrl:[MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]]
                                withSize:model.totalSize
                                withType:model.musicType];
            //同步
            NSDictionary *newMusicDowned = @{@"fileID":model.musicID,@"fileName":model.fileName,@"id":[NSString stringWithFormat:@"%d",((int)musicDownedArr.count+1)],@"size":model.totalSize,@"type":model.musicType,@"url":[MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]]};
            NSMutableArray *newMusicArr = [[NSMutableArray alloc]initWithArray:musicDownedArr];
            [newMusicArr addObject:newMusicDowned];
            [[UserManager standerDefult] setDownedMusicArr:newMusicArr];

        }
        
        isAllPause = NO;
        if ([UserManager standerDefult].downingMusicCountArr.count <= DOWNING_MUSIC_COUNT) {
            BOOL isExit = NO;
            DownMusicModel *nMusicModel;
            for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                if ([nM.musicID intValue] == [model.musicID intValue] && [nM.musicType intValue] == [model.musicType intValue]) {
                    isExit = YES;
                    nMusicModel = nM;
                }
            }
            if (isExit == YES) {
                //已下载完成 删除该nextModel，加载别的nextModel
                [[UserManager standerDefult].downingMusicCountArr removeObject:nMusicModel];
                
                if ([UserManager standerDefult].waitDownMusicCountArr.count > 0) {
                    DownMusicModel *nextModel = [[UserManager standerDefult].waitDownMusicCountArr firstObject];
                    BOOL isExit = NO;
                    for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                        if ([nM.musicID intValue] == [nextModel.musicID intValue] && [nM.musicType intValue] == [nextModel.musicType intValue]) {
                            isExit = YES;
                        }
                    }
                    if (isExit == NO) {
                        [[UserManager standerDefult].downingMusicCountArr addObject:nextModel];
                        //开始下载
                        [self start:[NSString stringWithFormat:@"%@.mp3",nextModel.fileName]];
                        [[UserManager standerDefult].waitDownMusicCountArr removeObject:nextModel];
                    }
                }
                
            }
            
        }
       
    }
   
    if (error) {
        if (model.stateBlock) {
            model.stateBlock(DownMusicState_Failed);
        }
        
    } else {
      //没问题，但是下载完成了，没下载全的
        if (isCompeted == NO) {
            isCompeted = YES;
            
            if (model.stateBlock) {
                model.stateBlock(DownMusicState_Completed);
            }
            
            //写入数据库
            FMManageObject *managerFM = [FMManageObject standerDefault];
            
            if (model.userID.length > 0) {
                //亲子秀
                NSDictionary *dic = [[managerFM onSelectLocalParentChildShowCount]lastObject];
                [managerFM insertTableByLocalParentChildShowWithId:[NSString stringWithFormat:@"%d",[[dic objectForKey:@"id"] intValue]+1] withTitle:model.fileName withUserId:model.userID withMusicId:model.musicID withContent:model.content withType:model.musicType withPicture:model.picUrl withDate:model.date withMp3:model.url withUserPic:model.userPic withUserNick:model.userNick withSize:model.size];
                
            } else {
                
                NSArray *musicDownedArr = [managerFM onSelectCustomMusicFileCount];
                [managerFM insertTableWithId:[NSString stringWithFormat:@"%d",((int)musicDownedArr.count+1)]
                                withFileName:model.fileName
                                  withFileID:model.musicID
                                     withUrl:[MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]]
                                    withSize:model.totalSize
                                    withType:model.musicType];
                //同步
                NSDictionary *newMusicDowned = @{@"fileID":model.musicID,@"fileName":model.fileName,@"id":[NSString stringWithFormat:@"%d",((int)musicDownedArr.count+1)],@"size":model.totalSize,@"type":model.musicType,@"url":[MusicCachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp3",model.fileName]]};
                NSMutableArray *newMusicArr = [[NSMutableArray alloc]initWithArray:musicDownedArr];
                [newMusicArr addObject:newMusicDowned];
                [[UserManager standerDefult] setDownedMusicArr:newMusicArr];
                
            }
            
            isAllPause = NO;
            if ([UserManager standerDefult].downingMusicCountArr.count <= DOWNING_MUSIC_COUNT) {
                BOOL isExit = NO;
                DownMusicModel *nMusicModel;
                for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                    if ([nM.musicID intValue] == [model.musicID intValue] && [nM.musicType intValue] == [model.musicType intValue]) {
                        isExit = YES;
                        nMusicModel = nM;
                    }
                }
                if (isExit == YES) {
                    //已下载完成 删除该nextModel，加载别的nextModel
                    [[UserManager standerDefult].downingMusicCountArr removeObject:nMusicModel];
                    
                    if ([UserManager standerDefult].waitDownMusicCountArr.count > 0) {
                        DownMusicModel *nextModel = [[UserManager standerDefult].waitDownMusicCountArr firstObject];
                        BOOL isExit = NO;
                        for (DownMusicModel *nM in [UserManager standerDefult].downingMusicCountArr) {
                            if ([nM.musicID intValue] == [nextModel.musicID intValue] && [nM.musicType intValue] == [nextModel.musicType intValue]) {
                                isExit = YES;
                            }
                        }
                        if (isExit == NO) {
                            [[UserManager standerDefult].downingMusicCountArr addObject:nextModel];
                            //开始下载
                            [self start:[NSString stringWithFormat:@"%@.mp3",nextModel.fileName]];
                             [[UserManager standerDefult].waitDownMusicCountArr removeObject:nextModel];
                        }
                    }
                    
                }
                
            }


        }
    }
    //清除临时
    if ([[UserManager standerDefult].tempMusicArr containsObject:[NSString stringWithFormat:@"%@",model.musicID]]) {
        [[UserManager standerDefult].tempMusicArr removeObject:[NSString stringWithFormat:@"%@",model.musicID]];
    }
    if ([self.tasks.allKeys containsObject:[NSString stringWithFormat:@"%@.mp3",model.fileName]]) {
        [self.tasks removeObjectForKey:[NSString stringWithFormat:@"%@.mp3",model.fileName]];
    }
    if ([self.sessionModels.allKeys containsObject:@(task.taskIdentifier).stringValue]) {
        [self.sessionModels removeObjectForKey:@(task.taskIdentifier).stringValue];
    }
    if ([self.downloadingArray containsObject:model]) {
        [self.downloadingArray removeObject:model];
    }

    _userId = @"";
    _content = @"";
    _picUrl = @"";
    _date = @"";
    _userPic = @"";
    _userNick = @"";
    _fileSize = @"";
    isQZX = NO;
    
    if (error)    return;   // cancel
    
    BOOL isExit = NO;
    NSMutableArray *nnsArr = [[NSMutableArray alloc]init];
    for (DownMusicModel *nM in self.sessionModelsArray) {
        if ([nM.musicID intValue] == [model.musicID intValue]) {
            isExit = YES;
            [nnsArr addObject:nM];
        }
    }
    if (isExit == YES) {
        [self.sessionModelsArray removeObjectsInArray:nnsArr];
    }


    //清除数据
    NSFileManager *fileManager = [NSFileManager defaultManager];
//    NSArray *sessionModels = [NSKeyedUnarchiver unarchiveObjectWithFile:[MusicCachesDirectory stringByAppendingPathComponent:@"downingloadDetail.data"]];
//    NSMutableArray *nSessionModel = [[NSMutableArray alloc]initWithArray:sessionModels];
//    for (DownMusicModel *musicMl in sessionModels) {
//        if ([musicMl.musicID intValue] == [model.musicID intValue] && [musicMl.musicType intValue]==[model.musicType intValue]) {
//            [nSessionModel removeObject:musicMl];
//        }
//    }
//    if ([fileManager fileExistsAtPath:[MusicCachesDirectory stringByAppendingPathComponent:@"downingloadDetail.data"]]) {
//        [fileManager removeItemAtPath:[MusicCachesDirectory stringByAppendingPathComponent:@"downingloadDetail.data"] error:nil];
//    }
//    [NSKeyedArchiver archiveRootObject:nSessionModel toFile:[MusicCachesDirectory stringByAppendingPathComponent:@"downingloadDetail.data"]];
    
    
    if ([fileManager fileExistsAtPath:DownloadDetailPath]) {
        [fileManager removeItemAtPath:DownloadDetailPath error:nil];
    }
    [NSKeyedArchiver archiveRootObject:self.sessionModelsArray toFile:DownloadDetailPath];
    
   
    
    if (![self.downloadedArray containsObject:model]) {
        [self.downloadedArray addObject:model];
    }
}

@end
